package study.sharding.spring.support.routing;

import com.alibaba.druid.pool.DruidDataSource;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import javax.sql.DataSource;
import java.util.Map;

/**
 * （1）@ConditionalOnSingleCandidate
 * 表示当指定 Bean 在容器中只有一个，或者虽然有多个但是指定首选 Bean
 * （2）@DependsOn
 * ==================================================
 * 自定义多数据源并且使用 mybatis auto config 时
 * （1）定义多个 datasource 时提示 "Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required"
 * 这是因为自定义多数据源时导致 MybatisAutoConfiguration 失效，@ConditionalOnSingleCandidate(DataSource.class)
 * 可以使用 @Primary 解决
 * （2）如果想使用 RoutingDataSource 为主类时提示 "BeanCurrentlyInCreationException: Error creating bean with name 'dataSource':
 * Requested bean is currently in creation: Is there an unresolvable circular reference?"
 * 可以是用 @DependsOn({"master", "slave"}) 解决
 */
@Slf4j
@Configuration
public class DataSourceConfig {

    /**
     * 物理数据源
     */
    @Primary
    @Bean
    @ConfigurationProperties(prefix = "datasource.master")
    public DataSource master() {
        DataSource dataSource = DataSourceBuilder.create()
                .type(DruidDataSource.class)
                .build();
        return dataSource;
    }

    @Bean
    @ConfigurationProperties(prefix = "datasource.slave")
    public DataSource slave() {
        DataSource dataSource = new DruidDataSource();
        return dataSource;
    }

//    /**
//     * 逻辑数据源
//     */
//    @Bean
//    public RoutingDataSource dataSource(@Qualifier("master") DataSource master,
//                                        @Qualifier("slave") DataSource slave) {
//        Map<Object, Object> dataSources = Maps.newHashMap();
//        dataSources.put("master", master);
//        dataSources.put("slave", slave);
//
//        RoutingDataSource dataSource = new RoutingDataSource();
//        dataSource.setDefaultTargetDataSource(master);
//        dataSource.setTargetDataSources(dataSources);
//        return dataSource;
//    }
}
